package evolutionaryLoop.selectionMechanisme;

import java.util.List;

import evolutionaryProblems.Phenotype;

public abstract class GlobalSelectionMechanisme extends SelectionMechanism {

	protected List<Phenotype> phenotypeList;
	protected List<Double> scaledFitnessList;

	public Phenotype select() {
//		System.out.println(sumScaledFitness());
		double selection = Math.random();
		double cumSum = 0;
		int index = -1;
		do {
			index++;
			cumSum += scaledFitnessList.get(index);
		} while (cumSum < selection);
//		System.out.println(index);
		return phenotypeList.get(index);
	}

	protected double getSumOfFitness() {
		double sumOfFitness = 0;
		for (Phenotype problem : phenotypeList) {
			sumOfFitness += problem.getFitness();
		}
		return sumOfFitness;
	}

	protected double getAvgFitness() {
		double totalFitness = 0;
		for (Phenotype phenotyp : phenotypeList) {
			totalFitness += phenotyp.getFitness();
		}
		return totalFitness / phenotypeList.size();
	}

	protected double getStandardDivation() {
		double totalDiviation = 0;
		double avgFitness = getAvgFitness();
		for (Phenotype phenotype : phenotypeList) {
			totalDiviation += Math
					.pow((phenotype.getFitness() - avgFitness), 2);
		}
		return Math.sqrt(totalDiviation / phenotypeList.size());
	}

	protected double minScaledFitness() {
		double minFitness = Double.MAX_VALUE;
		for (double fitness : scaledFitnessList) {
			if (fitness < minFitness) {
				minFitness = fitness;
			}
		}
		return minFitness;
	}

	protected double maxScaledFitness() {
		double maxFitness = Double.MIN_VALUE;
		for (double fitness : scaledFitnessList) {
			if (fitness > maxFitness) {
				maxFitness = fitness;
			}
		}
		return maxFitness;
	}
	
	protected void normalizeScaledFitness(){
		double scaledFitnessSum = sumScaledFitness(); 
		for (int i = 0; i < scaledFitnessList.size(); i++){
			scaledFitnessList.set(i, scaledFitnessList.get(i)/scaledFitnessSum); 
		}
	}
	
	protected double sumScaledFitness(){
		double sum = 0; 
		for (double scaledFitness : scaledFitnessList) {
			sum += scaledFitness; 
		}
		return sum;
	}
}
